<template>
	<a-card>
		<a-row type="flex" align="left" :gutter="[16, 16]">
			<a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
				<a-form
					ref="formRef"
					name="custom-validation"
					:model="formState"
					v-bind="layout"
					@finish="handleFinish"
					@finishFailed="handleFinishFailed"
				>
					<a-row>
						<a-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6">
							<a-form-item has-feedback label="角色名称" name="name">
								<a-input
									v-model:value="formState.name"
									placeholder="请输入角色名称"
									autocomplete="off"
								/>
							</a-form-item>
						</a-col>

						<a-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6">
							<a-form-item :wrapper-col="{ span: 14 }">
								<a-button type="primary" html-type="submit">查询</a-button>
								<a-button style="margin-left: 10px" @click="resetForm"
									>重置</a-button
								>
							</a-form-item>
						</a-col>
					</a-row>
				</a-form>
			</a-col>
			<a-col :span="24">
				<a-button type="primary" @click="addRole">
					<template #icon><PlusOutlined /></template>
					创建
				</a-button>
			</a-col>
			<a-col :span="24">
				<a-table
					:columns="columns"
					:dataSource="dataSource"
					:pagination="pagination"
					@change="handleTableChange"
					:rowKey="
						(record, index) => {
							return record.id
						}
					"
					:scroll="{ x: 'calc(700px + 50%)' }"
				>
					<template #status="{ record }">
						<SWITCH
							:status="record.status == 0 ? false : true"
							:data="record"
							:disabled="record.id==1?true:false"
							@changeSwitch="changeSwitch"
						/>
					</template>
					<template #operate="{ record }">
						<a-space>
							<a-button type="primary" @click="handleEdit(record)"
								>编辑</a-button
							>
							<a-button type="default" @click="handleAuthEdit(record)"
								>权限</a-button
							>
							<a-popconfirm
								title="是否确定删除？"
								ok-text="是"
								cancel-text="否"
								:disabled="record.id == 1"
								@confirm="handelDelet(record)"
							>
								<a-button type="danger" :disabled="record.id == 1"
									>删除</a-button
								>
							</a-popconfirm>
						</a-space>
					</template>
				</a-table>
			</a-col>
		</a-row>
		<ROLEMODEL
			v-if="visible"
			:visible="visible"
			:model="model"
			:title="title"
			@close-modal="handleCancel"
			@ok="handleOk"
		/>
		<Authority
			v-if="authvisible"
			ref="autority"
			:visible="authvisible"
			:model="mdl"
			@cancel="handleCancel"
			@handleok="handleauthOk"
		/>
	</a-card>
</template>
<script>
import { cloneDeep } from 'lodash-es'
import { defineComponent, reactive, ref, computed, onMounted } from 'vue'
import { useStore } from 'vuex'
import {
	roleList,
	updateRoleStatus,
	createRole,
	updateRole,
	delRole,
	AllRoleGrantAuth
} from '/@/api/app.js'
import { message } from 'ant-design-vue'
import { PlusOutlined } from '@ant-design/icons-vue'
import {SWITCH} from '/@/components'
import ROLEMODEL from './modules/Role.vue'
import Authority from './modules/Authority.vue'
function arrToTree(arr, pid = null) {
	const res = []
	arr.forEach((item) => {
		if (item.pid === pid) {
			// 这样每次都需要遍历整个数组，因此时间复杂度为 n*n
			// const children = arrToTree(arr, item.id)

			// 往下递归时，每次数组的大小都在减小，每次都筛选掉父代元素，最终的时间复杂度为 n*logn
			const children = arrToTree(
				arr.filter((v) => v.pid !== pid),
				item.id
			)
			if (children.length) {
				res.push({ ...item, children })
			} else {
				res.push({ ...item })
			}
		}
	})
	return res
}
const columns = [
	{
		title: 'ID',
		dataIndex: 'id',
		key: 'id'
	},

	{
		title: '角色名称',
		dataIndex: 'name',
		key: 'name'
	},

	{
		title: '状态',
		dataIndex: 'status',
		key: 'status',
		slots: { customRender: 'status' }
	},
	{
		title: '操作',
		dataIndex: 'operate',
		key: 'operate',
		align: 'center',
		slots: { customRender: 'operate' }
	}
]

export default defineComponent({
	components: {
		SWITCH,
		PlusOutlined,
		ROLEMODEL,
		Authority
	},
	setup() {
		const store = useStore()
		const model = ref({})
		const dataSource = ref([])
		const editableData = reactive({})
		const value = ref(null)
		const loading = ref(false)
		const current = ref(1)
		const pageSize = ref(10)
		const total = ref(0)
		const title = ref('')
		const visible = ref(false)
		const authvisible = ref(false)
		const mdl = ref({})
		const pagination = computed(() => ({
			current: current.value * 1,
			pageSize: pageSize.value * 1,
			'show-size-changer': false,
			pageSizeOptions: ['10', '20', '50'],
			total: total //总条数
		}))
		const formRef = ref()
		const formState = reactive({})

		const layout = {
			labelCol: {
				style: {
					width: '80px',
					float: 'left',
					textAlign: 'center'
				}
			},
			wrapperCol: {
				span: 16
			}
		}

		const handleCancel = () => {
			visible.value = false
			authvisible.value = false
		}

		const handleFinish = (values) => {
			current.value = 1
			refalsh()
		}

		const handleFinishFailed = (errors) => {
			console.log(errors)
		}
		const handelDelet = (n) => {
			const { id } = n
			delRole([id])
				.then((res) => {
					message.success('删除成功')
					refalsh()
				})
				.catch(() => {})
		}
		const resetForm = () => {
			formState.name = ''
			formState.status = undefined
			getroleList({
				page: 1,
				pagesize: pageSize.value
			})
		}
		const addRole = () => {
			model.value.edit = false
			title.value = '创建角色'
			visible.value = true
		}
		const handleEdit = (n) => {
			model.value = n
			model.value.edit = true
			title.value = '编辑管理员'
			visible.value = true
		}
		const handleAuthEdit = (n) => {
			authvisible.value = true

			mdl.value.id = n.id
		}
		const handleValidate = (...args) => {
			console.log(args)
		}
		const edit = (key) => {
			editableData[key] = cloneDeep(
				dataSource.value.filter((item) => key === item.key)[0]
			)
		}

		const save = (key) => {
			Object.assign(
				dataSource.value.filter((item) => key === item.key)[0],
				editableData[key]
			)
			delete editableData[key]
		}
		const handleTableChange = (page, filters, sorter) => {
			const { current: pagenum, pageSize: pagesize } = page
			current.value = pagenum * 1
			pageSize.value = pagesize * 1
			refalsh()
		}
		const cancel = (key) => {
			delete editableData[key]
		}
		const getroleList = (params) => {
			roleList(params)
				.then((res) => {
					const {
						code,
						message,
						result: { list, count }
					} = res

					dataSource.value = list
					arrToTree(list,0)
					total.value = count
				})
				.catch(() => {})
		}

		// 搜索
		const onSearch = (searchValue) => {
			current.value = 1
			refalsh()
		}
		const handleOk = (n) => {
			const {
				values: { name, status },
				model: { id, edit }
			} = n
			var params = {}

		 
			params.name = name

			params.status = status * 1
			if (!edit) {
				// 新增
				createRole(params)
					.then((res) => {
						message.success('新增成功')
						visible.value = false
						refalsh()
					})
					.catch(() => {})
			} else {
				params.id = id
				updateRole(params)
					.then((res) => {
						message.success('修改成功')
						visible.value = false
						refalsh()
					})
					.catch(() => {})
			}
		}
		const handleauthOk = (n) => {
			if(!n.value.checked){
			 	return;
			}
		  const {id} = mdl.value;
			AllRoleGrantAuth({
				id,
				auth: n.value.checked
			}).then((res) => {
					message.success('权限修改成功');
					authvisible.value=false;
					refalsh();
				})
				.catch(() => {})
		}
		const changeSwitch = (n) => {
			const {
				data: { id },
				status
			} = n
			updateRoleStatus({
				id,
				status: status ? 1 : 0
			})
				.then((res) => {
					message.success('状态修改成功')
					refalsh()
				})
				.catch(() => {})
		}
		const refalsh = () => {
			getroleList({
				name: formState.name,
				status: formState.status,
				page: current.value * 1,
				pagesize: pageSize.value * 1
			})
		}
		onMounted(() => {
			refalsh()
		})
		return {
			formState,
			formRef,
			layout,
			visible,
			title,
			model,
			authvisible,
			addRole,
			handelDelet,
			handleFinishFailed,
			handleFinish,
			resetForm,
			handleValidate,
			handleauthOk,
			dataSource,
			pagination,
			value,
			total,
			loading,
			current,
			pageSize,
			columns,
			editingKey: '',
			editableData,
			edit,
			save,
			cancel,
			handleTableChange,
			getroleList,
			onSearch,
			changeSwitch,
			handleCancel,
			handleOk,
			handleEdit,
			refalsh,
			handleAuthEdit,
			mdl
		}
	}
})
</script>
<style scoped>
.editable-row-operations a {
	margin-right: 8px;
}
</style>